import { Directive, ElementRef, Input, OnChanges, OnDestroy, Renderer2, SimpleChanges } from '@angular/core';

@Directive({
  selector: '[appLoading]',
  standalone: false
})
export class LoadingDirective implements OnChanges, OnDestroy {
  @Input() appLoading: boolean = false;

  private loadingElement: HTMLElement | null = null;
  private originalContent: HTMLElement[] = [];
  private originalDisplay: string = '';

  constructor(
    private el: ElementRef,
    private renderer: Renderer2
  ) {}

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['appLoading']) {
      if (this.appLoading) {
        this.showLoading();
      } else {
        this.hideLoading();
      }
    }
  }

  ngOnDestroy(): void {
    this.hideLoading();
  }

  private showLoading(): void {
    if (this.loadingElement) {
      return; // 已经在显示loading
    }

    const element = this.el.nativeElement;

    // 保存原始内容
    this.originalContent = Array.from(element.children);
    this.originalDisplay = element.style.display || '';

    // 隐藏原始内容
    this.originalContent.forEach(child => {
      this.renderer.setStyle(child, 'display', 'none');
    });

    // 创建loading容器
    this.loadingElement = this.renderer.createElement('div');
    this.renderer.addClass(this.loadingElement, 'loading-container');

    // 设置loading容器样式
    this.renderer.setStyle(this.loadingElement, 'display', 'flex');
    this.renderer.setStyle(this.loadingElement, 'justify-content', 'center');
    this.renderer.setStyle(this.loadingElement, 'align-items', 'center');
    this.renderer.setStyle(this.loadingElement, 'min-height', '50px');
    this.renderer.setStyle(this.loadingElement, 'width', '100%');

    // 创建SVG loading图标
    const svgElement = this.createLoadingSvg();
    this.renderer.appendChild(this.loadingElement, svgElement);

    // 将loading元素添加到目标元素
    this.renderer.appendChild(element, this.loadingElement);
  }

  private hideLoading(): void {
    if (!this.loadingElement) {
      return;
    }

    const element = this.el.nativeElement;

    // 移除loading元素
    this.renderer.removeChild(element, this.loadingElement);
    this.loadingElement = null;

    // 恢复原始内容
    this.originalContent.forEach(child => {
      this.renderer.removeStyle(child, 'display');
    });

    this.originalContent = [];
  }

  private createLoadingSvg(): SVGElement {
    const svg = this.renderer.createElement('svg', 'svg');
    this.renderer.setAttribute(svg, 'width', '40');
    this.renderer.setAttribute(svg, 'height', '40');
    this.renderer.setAttribute(svg, 'viewBox', '0 0 50 50');
    this.renderer.addClass(svg, 'loading-spinner');

    const style = this.renderer.createElement('style');
    const styleText = this.renderer.createText(`
      .loading-spinner {
        animation: spin 1s linear infinite;
      }
      @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
      }
    `);
    this.renderer.appendChild(style, styleText);
    this.renderer.appendChild(svg, style);

    const circle = this.renderer.createElement('circle', 'svg');
    this.renderer.setAttribute(circle, 'cx', '25');
    this.renderer.setAttribute(circle, 'cy', '25');
    this.renderer.setAttribute(circle, 'r', '20');
    this.renderer.setAttribute(circle, 'fill', 'none');
    this.renderer.setAttribute(circle, 'stroke', '#1890ff');
    this.renderer.setAttribute(circle, 'stroke-width', '4');
    this.renderer.setAttribute(circle, 'stroke-linecap', 'round');
    this.renderer.setAttribute(circle, 'stroke-dasharray', '31.416');
    this.renderer.setAttribute(circle, 'stroke-dashoffset', '31.416');

    const circleStyle = this.renderer.createElement('style');
    const circleStyleText = this.renderer.createText(`
      circle {
        animation: dash 1.5s ease-in-out infinite;
      }
      @keyframes dash {
        0% {
          stroke-dasharray: 1, 150;
          stroke-dashoffset: 0;
        }
        50% {
          stroke-dasharray: 90, 150;
          stroke-dashoffset: -35;
        }
        100% {
          stroke-dasharray: 90, 150;
          stroke-dashoffset: -124;
        }
      }
    `);
    this.renderer.appendChild(circleStyle, circleStyleText);
    this.renderer.appendChild(svg, circleStyle);

    this.renderer.appendChild(svg, circle);

    return svg;
  }
}
